<?php
/*
PWision extension: Newspaper http://pw-newspaper.googlecode.com/
Copyright (C) 2009--12 Becheru Petru-Ioan

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
\mainpage PWision extension: Newspaper
<a href='http://pw-newspaper.googlecode.com/'>This project</a> is an extension to the <a href='http://pwision.googlecode.com/'>PWision toolkit</a> allowing a webdeveloper to make a newspaper website.
\author Becheru Petru-Ioan
\note The source code is released under <a href="http://www.gnu.org/licenses/gpl.txt" title='text of GNU GENERAL PUBLIC LICENSE Version 3'>GNU GENERAL PUBLIC LICENSE Version 3</a>.
	\version 2.5.1
	\todo BookmarksList and website sections should be rethinked as links to articles(such as collection articles)
*/


//adds the sections of pw-newspaper to autoload paths. See PautoloadPaths class documentation in pwision.inc
PautoloadPaths::AddPath('sections/sections_pw-newspaper');

/** 	The ArticleInfo class is designed to hold informations about an article: ID, Title, text, authors, keywords, sub-articles.
	*	\latexonly \label{PWision:Extensions:Newspaper:ArticleInfo} \index{extension} \index{newspaper} \index{article} \endlatexonly
	*	\brief article info.
	*	\version 1.11.0
	*/
class ArticleInfo
	{
	/// identification number of the article
	public $ID;
	/// title of the article
	public $Title='';
	/// title of the article
	public $absTitle='';
	/// text content of the article(in BBCode)
	public $text='';
	/// text content of the article(in HTML)
	public $HTML='';
	/// text content of the abstract of the article
	public $textAbstract='';
	/// list of the authors
	public $authors=null;
	/// list of the affiliations
	public $affiliations=null;
	/// list of the author -> affiliations (authorAffiliations[1]={1,3})
	public $authorAffiliations=null;
	/// list of the affiliation -> authors (affiliationsAuthors[1]={2,5})
	public $affiliationsAuthors=null;
	/// list of keywords
	public $keywords=null;
	/// classification
	public $classifications=null;
	/// the volume number
	public $Volume=null;
	/// the issue (can be a number, a range, or a text)
	public $Issue=null;
	/// first page number of the article
	public $firstPage=null;
	/// last page number of the article
	public $lastPage=null;
	/// the PDF file of the article
	public $pdfURL=null;
	/// the cover image of the article
	public $coverURL=null;
	/// the source file of the article (should be be a .doc, .tex or .zip file)
	public $sourceURL=null;
	/// the main language of the article
	public $Language=null;
	/// the language of the abstract
	public $absLanguage=null;
	/// the language of the keywords of the article
	public $KwLanguage=null;
	/// list of log messages
	public $logs=null;
	/// list of sub-articles
	public $sub_articles=null;
	/// list of articles that this article is a sub-article for them
	public $owners=null;
	/// list of articles that form a path to this article
	public $owner_path=null;
	/// publication year
	public $Year=null;
	/// publication month
	public $Month=null;
	/// publication day
	public $Day=null;
	
	
	private static function lang639_1to639_2($lang)
		{
		static $to=array
			(// http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
			'ro'=> 'rum',
			'la'=> 'lat',
			'en' => 'eng',
			'fr' => 'fre',
			'de' => 'ger',
			'es' => 'spa'
			);
		return $to[$lang];
		}
	
	/**
		* \brief RePEc record for an article
		* \return record according to http://ideas.repec.org/t/articletemplate.html
		*	\version 1.1.0
		*/
	function RePEc()
		{
		$record='';
		$record.='Template-Type: ReDIF-Article 1.0';
		foreach($this->authors as $key=>$author)
			{
			$record.="\n".'Author-Name:  '.$author;
			if($this->authorAffiliations && isset($this->authorAffiliations[$key+1]))
				foreach($this->authorAffiliations[$key+1] as $affiliation)
					$record.="\n".'Author-Workplace-Name: '.$this->affiliations[$affiliation-1];
			}
/*		foreach($this->affiliations as $key=>$affiliation)
			{
			if($this->affiliationsAuthors)
				foreach($this->affiliationsAuthors[$key+1] as $author_i)
					{
					$record.="\n".'Author-Name:  '.$this->authors[$author_i-1];
					}
			$record.="\n".'Author-Workplace-Name: '.$affiliation;
			}*/
		$record.="\n".'Title:  '.$this->Title;
		$record.="\n".'Abstract:  '.preg_replace('`[[:space:]]+`',' ',$this->textAbstract);
		if($this->classifications)
		$record.="\n".'Classification-JEL: '.implode(', ',$this->classifications);
		if($this->keywords)
		$record.="\n".'Keywords: '.implode(', ',$this->keywords);
		$record.="\n".'Journal: '.Main()->getFullTitle();
		$record.="\n".'Pages: '.$this->firstPage.'-'.$this->lastPage;
		$record.="\n".'Volume: '.$this->Volume;
		$record.="\n".'Issue: '.$this->Issue;
		$record.="\n".'Year: '.$this->Year;
		$record.="\n".'Month: '.pwision_newspaper_Article::$Month[(int)$this->Month];
		if($this->pdfURL)
			{
			$record.="\n".'File-URL: '.$this->pdfURL;
			$record.="\n".'File-Format: Application/pdf';
			}
		$record.="\n".'File-URL: '.'http://'.$_SERVER['HTTP_HOST'].'/('.$this->ID.')';
		$record.="\n".'File-Format: text/html';
		$record.="\n".'Number: '.$this->ID;
		
		$record.="\n".'Handle: RePEc:'.Main()->getREPEC().':'.Main()->getREPECj().':v:'.$this->Volume.':y:'.$this->Year.':i:'.$this->Issue.':p:'.$this->firstPage.'-'.$this->lastPage;
		return new PText($record);
		}
	/**
		* \brief DOAJ record for an article
		* \return record according to http://www.doaj.org/doaj?func=loadTempl&templ=uploadInfo&uiLanguage=en
		*/
	function DOAJ()
		{
		$record=El('record');
		
		$record->Insert(
			El('language')
				->Insert(new PText(ArticleInfo::lang639_1to639_2(($this->Language=='')?Main()->getLanguage():$this->Language)))
			);
		
		if(Main()->getPublisher())
		$record->Insert(
			El('publisher')
				->Insert(new PText(Main()->getPublisher()))
			);
			
		$record->Insert(
			El('journalTitle')
				->Insert(new PText(Main()->getFullTitle()))
			);
		
		if(Main()->getISSN() && Main()->getISSN()!=Main()->geteISSN())
		$record->Insert(
			El('issn')
				->Insert(new PText(Main()->getISSN()))
			);
		
		if(Main()->geteISSN())
		$record->Insert(
			El('eissn')
				->Insert(new PText(Main()->geteISSN()))
			);
		
		if($this->Year && $this->Month && $this->Day)
		$record->Insert(
			El('publicationDate')
				->Insert(new PText($this->Year.'-'.$this->Month.'-'.$this->Day))
			);
		
		if($this->Volume)
		$record->Insert(
			El('volume')
				->Insert(new PText($this->Volume))
			);
		
		if($this->Issue)
		$record->Insert(
			El('issue')
				->Insert(new PText($this->Issue))
			);
		
		if($this->firstPage)
		$record->Insert(
			El('startPage')
				->Insert(new PText($this->firstPage))
			);
		
		if($this->lastPage)
		$record->Insert(
			El('endPage')
				->Insert(new PText($this->lastPage))
			);
		
		$record->Insert(
			El('publisherRecordId')
				->Insert(new PText($this->ID))
			);
		
		$record->Insert(
			El('title')
					->setAtr('language',ArticleInfo::lang639_1to639_2(($this->Language=='')?Main()->getLanguage():$this->Language))
				->Insert(new PText($this->Title))
			);
		
		if(
			(($this->absLanguage=='')?Main()->getLanguage():$this->absLanguage)
				!=
			(($this->Language=='')?Main()->getLanguage():$this->Language)
					
					&&
					
			$this->absTitle
			)
		$record->Insert(
			El('title')
				->setAtr('language',ArticleInfo::lang639_1to639_2(($this->absLanguage=='')?Main()->getLanguage():$this->absLanguage))
				->Insert(new PText($this->absTitle))
			);
		
		$authors=new PStructure(
			El('author'),
			El('authors')
			);
		if($this->authors)
		foreach($this->authors as $key=>$author_name)//(authorAffiliations[1]={1,3})
			{
			$author=$authors->newKid();
			$author->Insert(
				El('name')
					->Insert(new PText($author_name))
				);
			if($this->authorAffiliations && isset($this->authorAffiliations[$key+1]))
				foreach($this->authorAffiliations[$key+1] as $affiliation)
					$author->Insert(
						El('affiliationId')
							->Insert(new PText($affiliation))
						);
			}
		$record->Insert($authors);
		
		
		$affiliations=new PStructure(
			El('affiliationName'),
			El('affiliationsList')
			);
		if($this->affiliations)
		foreach($this->affiliations as $key=>$affiliation)
			{
			$affiliations->newKid()
					->setAtr('affiliationId',$key+1)
				->Insert(new PText($affiliation));
			}
		$record->Insert($affiliations);
		
		if($this->textAbstract)
		$record->Insert(
			El('abstract')
					->setAtr('language',ArticleInfo::lang639_1to639_2(($this->absLanguage=='')?Main()->getLanguage():$this->absLanguage))
				->Insert(
					new PText(
						htmlspecialchars(preg_replace('`[[:space:]]+`',' ',$this->textAbstract))
						)
					)
			);
		
		if($this->pdfURL)
		$record->Insert(
			El('fullTextUrl')
				->setAtr('format','PDF')
				->Insert(new PText($this->pdfURL))
			);
		
		if($this->text)
		$record->Insert(
			El('fullTextUrl')
				->setAtr('format','HTML')
				->Insert(new PText(
					'http://'.$_SERVER['HTTP_HOST'].'/('.$this->ID.')'
					))
			);
		
		if($this->keywords)
			{
			$keywords=new PStructure(
				El('keyword'),
				El('keywords')
					->setAtr('language',ArticleInfo::lang639_1to639_2(($this->KwLanguage=='')?Main()->getLanguage():$this->KwLanguage))
				);
			foreach($this->keywords as $keyword)
				$keywords->newKid()
					->Insert(new PText($keyword))
					;
			$record->Insert($keywords);
			}
		return $record;
		}
	}

/**	Explodes and trims a string into keywords.
	*	\brief explode and trim.
	*	\version 1.0.1
	*	\param $keywords_list the input string
	*	\param $delimiter the delimiter string
	*	\param $k_no the maximum number of keyword
	*	\return an array of strings, null if no empty keywords found
	*/
function explodeNtrim($keywords_list,$delimiter=',',$k_no=128)
	{
	$keywords=array_unique(
		explode(
			$delimiter,//comma delimiter
			$keywords_list,
			$k_no// maximum number of keywords
			)
		);
	$ret=array();
		foreach($keywords as $keyword)
			{
			$trimmed_keyword=trim($keyword);
			if($trimmed_keyword!='')
				$ret[]=$trimmed_keyword;
			}
	return count($ret)?$ret:null;
	}

include_once("inc/PSection.inc");
include_once("inc/BBCode.inc");
include_once("inc/PMainComponent.inc");


/**	A namespace for newspaper functions.
	*	\brief newspaper's namespace.
	*	\version 2.1.3
	*/
final class NewsPaper
	{
	/**	Gets the data of an article from the NArticleTag and NTag DB tables.
		*	\brief gets the data of an article.
		*	\version 1.3.11
		*	\param $ID identification number of the article
		*	\return a ArticleInfo object if an article is found, null else
		*/
	function getArticleInfo($ID)
		{
		$NArticle=Main()->DB->fetch_array_query("select * from `NArticle` where ID='$ID'");
		if(!$NArticle)return null;
		$ret=new ArticleInfo;
			$ret->ID=$ID;
			$ret->Volume=$NArticle['Volume'];
			$ret->Issue=$NArticle['Issue'];
			$ret->firstPage=$NArticle['firstPage'];
			$ret->lastPage=$NArticle['lastPage'];
			$ret->pdfURL=$NArticle['pdfURL'];
			$ret->coverURL=$NArticle['coverURL'];
			$ret->sourceURL=$NArticle['sourceURL'];
			$ret->Language=$NArticle['Language'];
			$ret->absLanguage=$NArticle['absLanguage'];
			$ret->KwLanguage=$NArticle['KwLanguage'];
			$ret->textAbstract=$NArticle['textAbstract'];
			$ret->absTitle=$NArticle['abstractTitle'];
		$tags=Main()->DB->fetch_all_query("select * from NArticleTag where IDArticle='$ID' order by ID");
		$affiliations=array();
		if	(
			count($tags)==0 &&
			count( Main()->DB->fetch_all_query("select ID from NArticle where ID='$ID'") ) == 0
			)
				return null;
			else
				foreach($tags as $tag)
					{// see pw-newspaper DB @ http://docs.google.com/View?id=dckv45wd_44hhvzwpc2
					switch ($tag['IDTag'])
						{
						case 1: $ret->Title=$tag['TValue']; break;
						case 2: $ret->text=$tag['TValue']; break;
						case 12: 
							if(!$ret->affiliations)$ret->affiliations=array();
							$affiliations[$tag['ID']]=array_push($ret->affiliations,$tag['TValue']); 
							break;
						case 3: 
							if(!$ret->authors)$ret->authors=array();
							$authors[$tag['ID']]=array_push($ret->authors,$tag['TValue']); 
							break;
						case 4: $ret->keywords[]=$tag['TValue']; break;
						case 9: $ret->logs[]=$tag['TValue']; break;
						case 10: $ret->HTML=$tag['TValue']; break;
						case 11: $ret->classifications[]=$tag['TValue']; break;
						}
					}
		$tagRels=Main()->DB->fetch_all_query("select * from NArticleTagRel where IDArticle='$ID'");
		foreach($tagRels as $tagRel)
			{
			$authorID=$tagRel['NArticleTagID1'];
			$affiliationID=$tagRel['NArticleTagID2'];
			if(array_key_exists($authorID,$authors) && array_key_exists($affiliationID,$affiliations))
				{
				$ret->authorAffiliations[$authors[$authorID]][]=$affiliations[$affiliationID];
				$ret->affiliationsAuthors[$affiliations[$affiliationID]][]=$authors[$authorID];
				}
			}
/*
select distinct
	sub_articles.IDArticle `ID`,
	sub_articles.TValue `Title`,
	min(logs.TValue) `Creation`
from
	NArticleTag `main`,
	NArticleTag `sub_articles`,
	NArticleTag `logs`
where
	main.IDArticle='$ID' and
	main.IDTag=6 and
	main.TValue=sub_articles.IDArticle and
	sub_articles.IDTag=1 and
	logs.IDArticle=sub_articles.IDArticle and
	logs.IDTag=9
group by
	`ID`,
	`Title`
order by
	`Creation` DESC,
	`ID` ASC
*/
		$sub_arts=
			Main()->DB->fetch_all_query 
// 			print
			("select distinct NArticle.*, sub_articles.TValue `Title`, min(logs.TValue) `Creation` from NArticleTag `main`, NArticleTag `sub_articles`, NArticleTag `logs`, NArticle where main.IDArticle='$ID' and main.IDTag=6 and main.TValue=sub_articles.IDArticle and sub_articles.IDTag=1 and logs.IDArticle=sub_articles.IDArticle and logs.IDTag=9 and NArticle.ID=sub_articles.IDArticle group by `ID`,`Title` order by Volume+0 DESC, Issue+0 DESC, firstPage+0 ASC, lastPage+0 ASC,`Creation` DESC, `ID` ASC");
// 			print_r($sub_arts);
		if(count($sub_arts))
			{
			foreach($sub_arts as &$sub_art)
				{
				$sub_art['Authors']=array_column( Main()->DB->fetch_all_query('select TValue from NArticleTag where IDArticle='.$sub_art['ID'].' and IDTag=3 order by ID'), 'TValue' );
				}
			$ret->sub_articles=$sub_arts;
			}
		$owners=Main()->DB->fetch_all_query ("select distinct main.IDArticle `ID`, main.TValue `Title`, min(logs.TValue) `Creation` from NArticleTag `main`, NArticleTag `owners`, NArticleTag `logs` where owners.IDTag=6 and owners.TValue='$ID' and owners.IDArticle=main.IDArticle and main.IDTag=1 and logs.IDArticle=owners.IDArticle and logs.IDTag=9 group by `ID`,`Title` order by `Creation` DESC, `ID` ASC");
		if(count($owners))
			{//this article has owners
			$ret->owners=$owners;
			$ret->owner_path=NewsPaper::owner_path($ID);
			}
		$matches=array();
		preg_match(
			'`^([0-9]{4})-([0-9]{2})-([0-9]{2})`',
			$ret->logs[count($ret->logs)-1],
			$matches
			);
		$ret->Year=isset($matches[1])?$matches[1]:null;
		$ret->Month=isset($matches[2])?$matches[2]:null;
		$ret->Day=isset($matches[3])?$matches[3]:null;
		return $ret;
		}
	/**	While we have an owner, get its owner.
		*	\brief builds the owner path for an article
		*	\param $ID identification number of the article
		*	\return the list of articles that form a path to this article
		*/
	function owner_path($ID)
		{
		$ret=array();
		$maxdepth=20;
		while($maxdepth-- && $row=Main()->DB->fetch_array_query("select distinct main.IDArticle `ID`, main.TValue `Title`, min(logs.TValue) `Creation` from NArticleTag `main`, NArticleTag `owners`, NArticleTag `logs` where owners.IDTag=6 and owners.TValue='$ID' and owners.IDArticle=main.IDArticle and main.IDTag=1 and logs.IDArticle=owners.IDArticle and logs.IDTag=9 group by `ID`,`Title` order by `Creation` DESC, `ID` ASC limit 0,1"))
			{
			$ret[]=$row;
			$ID=$row['ID'];
			}
		return array_reverse($ret);
		return $ret;
		}
	/**	Creates a new articles using the arguments.
		*	\brief create a new article.
		*	\version 1.0.2
		*	\param $article ArticleInfo object that is used for article creation
		*	\return ID of the article on succes, false else.
		*/
	function CreateArticle( ArticleInfo &$article)
		{
		Main()->DB->query('insert into `NArticle` () values ()');
		$ID=mysql_insert_id();
		//title
		Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,1,'".$article->Title."')");
		//text
		Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,2,'".$article->text."')");
		//authors
		if($article->authors)
		foreach($article->authors as $author)
			{
			$author=ucwords(strtolower($author));
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,3,'$author')");
			}
		//affiliations
		if($article->affiliations)
		foreach($article->affiliations as $affiliation)
			{
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,12,'$affiliation')");
			}
		//keywords
		if($article->keywords)
		foreach($article->keywords as $keyword)
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,4,'$keyword')");
		//logs
		if($article->logs)
		foreach($article->logs as $log)
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,9,'$log')");
		//sub_articles
		if($article->sub_articles)
		foreach($article->sub_articles as $sub_article)
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,6,'$sub_article')");
		//owners
		if($article->owners)
		foreach($article->owners as $owner)
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ('$owner',6,'$ID')");

		return $ID;
		}
	/**	Clean an article of its tags(title,content etc).
		*	\brief clear an article's tags.
		*	\version 1.0.1
		*	\param $ID the id of the article
		*	\return ID of the article on succes, false else.
		*/
	function CleanArticle($ID)
		{
		//tag relations
		Main()->DB->query("delete from `NArticleTagRel` where `IDArticle`='$ID'");
		//title,text,authors,affiliations,keywords,logs,sub_articles
		Main()->DB->query("delete from `NArticleTag` where `IDArticle`='$ID'");
		//owners
		Main()->DB->query("delete from `NArticleTag` where `IDTag`=6 and `TValue`='$ID'");
		//article exists?
		return Main()->DB->fetch_array_query("select ID from `NArticle` where ID='$ID'")?$ID:false;
		}
	/**	After cleaning it of its tags, an article is deleted form NArticle table .
		*	\brief delete an article.
		*	\param $ID the id of the article
		*/
	function rmArticle($ID)
		{
		NewsPaper::CleanArticle($ID);
		//delete form NArticle table
		Main()->DB->query("delete from `NArticle` where `ID`='$ID'");
		}
	/**
		* \brief Capitalize all words
		* \param $words Data to capitalize
		* \param $charList Word delimiters
		* \return string Capitalized words
		*/
	protected function capitalizeWords($words, $charList = null)
		{
		// Use ucwords if no delimiters are given
		if (!isset($charList)) {
			return ucwords($words);
		}

		// Go through all characters
		$capitalizeNext = true;

		for ($i = 0, $max = strlen($words); $i < $max; $i++) {
			if (strpos($charList, $words[$i]) !== false) {
					$capitalizeNext = true;
			} else if ($capitalizeNext) {
					$capitalizeNext = false;
					$words[$i] = strtoupper($words[$i]);
			}
		}

		return $words;
		}

	/**	Edits an article using the arguments.
		*	\brief edit an article.
		*	\version 1.0.10
		*	\param $article ArticleInfo object that is used for article edit
		*	\return ID of the article on succes, false else.
		*	\note if a log entry starts with '-', it is not inserted as a log
		*/
	function EditArticle( ArticleInfo &$article)
		{
		if( ($ID=NewsPaper::CleanArticle($article->ID))==false)return false;
		//title
		Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,1,'".$article->Title."')");
		//text
		Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,2,'".$article->text."')");
		//HTML
		if($article->Language)
			$article->text=
				'[lang='.$article->Language.']'.
					$article->text.
				'[/lang]';
		Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,10,'".BBCode::BBCode2HTML($article->text)."')");
		//affiliations
		$affiliationsIDs=array();
		if($article->affiliations)
		foreach($article->affiliations as $affiliation)
			{
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,12,'$affiliation')");
			$affiliationsIDs[]=mysql_insert_id();
			}
		//authors
		if($article->authors)
		foreach($article->authors as $authorNA)
			{
			preg_match('`([^*]*)([*]\s*([0-9 ]*))?$`', $authorNA, $authorNAsplit);
			$author=$authorNAsplit[1];
			$author=NewsPaper::capitalizeWords(strtolower($author),' -.');
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,3,'$author')");
			$authorID=mysql_insert_id();
			if(array_key_exists(3,$authorNAsplit))
				{
				$affiliations=array_unique(explode(' ',$authorNAsplit[3]));
				foreach($affiliations as $affiliation)
					if(strlen($affiliation) && array_key_exists($affiliation-1,$affiliationsIDs))
						{
						$affiliationID=$affiliationsIDs[$affiliation-1];
						Main()->DB->query
// 						print
						("insert into `NArticleTagRel` (`IDArticle`,`NArticleTagID1`,`NArticleTagID2`) values ($ID,'$authorID','$affiliationID')");
						}
				}
			}
		//keywords
		if($article->keywords)
		foreach($article->keywords as $keyword)
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,4,'$keyword')");
		//keywords
		if($article->classifications)
		foreach($article->classifications as $classification)
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,11,'$classification')");
		//logs
		if($article->logs)
		foreach($article->logs as $log)
			if($log[0]!='-')
				Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,9,'$log')");
		//sub_articles
		if($article->sub_articles)
		foreach($article->sub_articles as $sub_article)
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ($ID,6,'$sub_article')");
		//owners
		if($article->owners)
		foreach($article->owners as $owner)
			Main()->DB->query("insert into `NArticleTag` (`IDArticle`, `IDTag`, `TValue`) values ('$owner',6,'$ID')");
			
		if($article->Volume && strlen($article->Volume))
				Main()->DB->query("UPDATE `NArticle` SET `Volume`='".$article->Volume."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `Volume`=NULL WHERE  `ID` = '$ID'");
		if($article->Issue && strlen($article->Issue))
				Main()->DB->query("UPDATE `NArticle` SET `Issue`='".$article->Issue."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `Issue`=NULL WHERE  `ID` = '$ID'");
		if($article->firstPage && strlen($article->firstPage))
				Main()->DB->query("UPDATE `NArticle` SET `firstPage`='".$article->firstPage."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `firstPage`=NULL WHERE  `ID` = '$ID'");
		if($article->lastPage && strlen($article->lastPage))
				Main()->DB->query("UPDATE `NArticle` SET `lastPage`='".$article->lastPage."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `lastPage`=NULL WHERE  `ID` = '$ID'");
		if($article->pdfURL && strlen($article->pdfURL))
				Main()->DB->query("UPDATE `NArticle` SET `pdfURL`='".$article->pdfURL."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `pdfURL`=NULL WHERE  `ID` = '$ID'");
		if($article->sourceURL && strlen($article->sourceURL))
				Main()->DB->query("UPDATE `NArticle` SET `sourceURL`='".$article->sourceURL."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `sourceURL`=NULL WHERE  `ID` = '$ID'");
		if($article->coverURL && strlen($article->coverURL))
				Main()->DB->query("UPDATE `NArticle` SET `coverURL`='".$article->coverURL."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `coverURL`=NULL WHERE  `ID` = '$ID'");
		if($article->Language && strlen($article->Language))
				Main()->DB->query("UPDATE `NArticle` SET `Language`='".$article->Language."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `Language`=NULL WHERE  `ID` = '$ID'");
		if($article->absLanguage && strlen($article->absLanguage))
				Main()->DB->query("UPDATE `NArticle` SET `absLanguage`='".$article->absLanguage."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `absLanguage`=NULL WHERE  `ID` = '$ID'");
		if($article->KwLanguage && strlen($article->KwLanguage))
				Main()->DB->query("UPDATE `NArticle` SET `KwLanguage`='".$article->KwLanguage."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `KwLanguage`=NULL WHERE  `ID` = '$ID'");
		if($article->textAbstract && strlen($article->textAbstract))
				Main()->DB->query("UPDATE `NArticle` SET `textAbstract`='".$article->textAbstract."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `textAbstract`=NULL WHERE  `ID` = '$ID'");
		if($article->absTitle && strlen($article->absTitle))
				Main()->DB->query("UPDATE `NArticle` SET `abstractTitle`='".$article->absTitle."' WHERE  `ID` = '$ID'");
			else
				Main()->DB->query("UPDATE `NArticle` SET `abstractTitle`=NULL WHERE  `ID` = '$ID'");

		return $ID;
		}
	}

/** 	The PNewsPaperSitemap class is designed to model the sitemap webpage of NewsPaper extended PWision website.
	*	\latexonly \label{PWision:Extensions:Newspaper:PNewsPaperSitemap} \index{PNewsPaperSitemap} \index{PSitemap} \index{sitemap} \endlatexonly
	*	\brief the sitemap webpage.
	*	\version 1.0.1
	*	\par Example:
	*		See the code example of PSitemap class.
	*	\par Output:
\verbatim
http://www.example.com/
http://www.example.com/(1)
http://www.example.com/(2)
http://www.example.com/(3)
http://www.example.com/(4)
http://www.example.com/(5)
\endverbatim
	*/
abstract class PNewsPaperSitemap extends PSitemap
	{
	protected function ConstructList()
		{
		PSitemap::ConstructList();
		/// the list of accessible sections, including the hidden ones
		$Articles=Main()->DB->fetch_all_query("select ID from `NArticle`");
		if(count($Articles)>0)
			foreach($Articles as $article)
				{
				$li=$this->ul->newKid();
				$li->Insert(
					new PText(
						$this->SiteURL().'('.$article['ID'].')'.
						"\n"
						)
					);
				}
		}
	}

/** 	The PNewsPaperWebPageDefault class is designed to be the default themed webpage of a PWision website, with NewsPaper extension enabled.
	*	\latexonly \label{PWision:Extensions:Newspaper:PWebPageDefault} \index{PWebPageDefault} \endlatexonly
	*	\brief PWision's default themed webpage(NewsPaper extension enabled).
	*	\version 1.4.0
	*/
abstract class PNewsPaperWebPageDefault extends PWebPageDefault
	{
	protected $ISSN='';
		function getISSN()
			{
			if($this->ISSN)
					return $this->ISSN;
				elseif($this->eISSN)
					return $this->ISSN;
				else
					return '';
			}
		function & setISSN($ISSN)
			{
			$this->ISSN=$ISSN;
			return $this;
			}
	protected $eISSN='';
		function geteISSN()
			{
			return $this->eISSN;
			}
		function & seteISSN($eISSN)
			{
			$this->eISSN=$eISSN;
			return $this;
			}
	protected $ISSNl='';
		function getISSNl()
			{
			return $this->ISSNl;
			}
		function & setISSNl($ISSNl)
			{
			$this->ISSNl=$ISSNl;
			return $this;
			}
	protected $REPEC='';
	protected $REPEC_journal='';
		function getREPEC()
			{
			return $this->REPEC;
			}
		function getREPECj()
			{
			return $this->REPEC_journal;
			}
		function & setREPEC($REPEC,$journal)
			{
			$this->REPEC=$REPEC;
			$this->REPEC_journal=$journal;
			return $this;
			}
	protected $Address;
		function getAddress()
			{
			return $this->Address;
			}
		function & setAddress($Address)
			{
			$this->Address=$Address;
			return $this;
			}
	function & setLanguage()
		{
		$filename='languages/pw-newspaper-lang-'.$this->Language.'.inc';
		if(file_exists($filename)){include($filename);}
		return parent::setLanguage();
		}
		protected function pwnewspaper_css()
			{
			return new PText(" @import \"/css/pw-newspaper.css\"; ") ;
			}
		protected function Head_Css()
			{
			return parent::Head_Css()
				->Insert( $this->pwnewspaper_css() )
				;
			}
	protected $fullTitle="";
	function getFullTitle()
		{
		if($this->fullTitle=="")
				return $this->getTitle();
			else
				return $this->fullTitle;
		}
	function & setFullTitle($fullTitle)
		{
		$this->fullTitle=$fullTitle;
		return $this;
		}
	protected $publisher="";
	function getPublisher()
		{
		return $this->publisher;
		}
	function & setPublisher($publisher)
		{
		$this->publisher=$publisher;
		return $this;
		}
	}

?>